import 'dart:async';

import 'package:flutter/material.dart';
import 'package:flutter/scheduler.dart';

import '../config.dart';
import '../hud.dart';

T? _ambiguate<T>(T? value) => value;

class HudContent extends StatefulWidget {
  const HudContent({
    super.key,
    required this.text,
    this.indicator,
    this.completer,
    this.dismisser,
    required this.position,
  });
  final String text;
  final Completer<void>? completer;
  final Completer<void>? dismisser;
  final HudPosition position;
  final Widget? indicator;
  @override
  State<HudContent> createState() => HudContentState();
}

class HudContentState extends State<HudContent>
    with SingleTickerProviderStateMixin {
  late AnimationController ac;

  bool get isPersistentCallbacks =>
      _ambiguate(SchedulerBinding.instance)!.schedulerPhase ==
      SchedulerPhase.persistentCallbacks;
  @override
  void initState() {
    if (!mounted) return;
    ac = AnimationController(vsync: this)
      ..duration = const Duration(milliseconds: 200)
      ..addStatusListener((status) {
        if (status == AnimationStatus.completed) {
          bool isCompleted = widget.completer?.isCompleted ?? false;
          if (status == AnimationStatus.completed && !isCompleted) {
            widget.completer?.complete();
          }
        }
      });
    show(true);
    super.initState();
  }

  Future<void> show(bool animation) {
    if (isPersistentCallbacks) {
      Completer<void> completer = Completer<void>();
      _ambiguate(SchedulerBinding.instance)!.addPostFrameCallback(
          (_) => completer.complete(ac.forward(from: animation ? 0 : 1)));
      return completer.future;
    } else {
      return ac.forward(from: animation ? 0 : 1);
    }
  }

  Future<void> dismiss(bool animation) {
    if (isPersistentCallbacks) {
      Completer<void> completer = Completer<void>();
      _ambiguate(SchedulerBinding.instance)!.addPostFrameCallback(
          (_) => completer.complete(ac.reverse(from: animation ? 1 : 0)));
      return completer.future;
    } else {
      return ac.reverse(from: animation ? 1 : 0);
    }
  }

  @override
  void dispose() {
    ac.dispose();
    widget.dismisser?.complete();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Stack(
      alignment: Alignment.center,
      children: [
        AnimatedBuilder(
            animation: ac,
            builder: (ctx, child) {
              return Opacity(
                opacity: ac.value,
                child: IgnorePointer(
                  ignoring: !Hud.instance.userInteractions,
                  child: HudToast(
                    text: widget.text,
                    indicator: widget.indicator,
                    position: widget.position,
                  ),
                ),
              );
            })
      ],
    );
  }
}
